import os
import subprocess
from PIL import Image
from reportlab.pdfgen import canvas
from PyPDF2 import PdfMerger

#下载wkhtmltox，配置好wkhtmltopdf.exe的路径
wkhtmltopdf_path = r'D:\Wkhtmltox\wkhtmltopdf\bin\wkhtmltopdf.exe'

candidates_dict = {} #储存考生号和姓名之间的对应关系

def clear_directory(directory):
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        try:
            if os.path.isfile(file_path) or os.path.islink(file_path):
                os.unlink(file_path)
            elif os.path.isdir(file_path):
                os.removedirs(file_path)
        except Exception as e:
            print(f'Failed to delete {file_path}. Reason: {e}')

def convert_html_to_pdf(input_path, output_path):
    command = [wkhtmltopdf_path,'--enable-local-file-access', input_path, output_path]
    try:
        subprocess.run(command, check=True)
        print(f"Successfully converted {input_path} to {output_path}.")
    except subprocess.CalledProcessError as e:
        print(f"Error converting {input_path} to PDF: {e}")

def convert_all_html_in_folder(input_folder, output_folder):
    # 如果输出文件夹不存在，创建文件夹
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # 遍历输入文件夹中的所有文件
    for filename in os.listdir(input_folder):
        if filename.endswith(".htm") or filename.endswith(".html"):
            input_path = os.path.join(input_folder, filename)
            output_filename = os.path.splitext(filename)[0] + '.pdf'
            output_path = os.path.join(output_folder, output_filename)

            # 调用转换函数
            convert_html_to_pdf(input_path, output_path)

def convert_gif_to_jpg(input_folder, temp_folder):
    
    # 确保临时文件夹存在
    if not os.path.exists(temp_folder):
        os.makedirs(temp_folder)

    # 遍历输入文件夹中的所有文件
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.gif'):
            # 打开GIF文件
            img_path = os.path.join(input_folder, filename)
            img = Image.open(img_path)
            
            # 将GIF转换为单帧图像
            if img.is_animated:
                # 选择第一帧
                img.seek(0)
                img = img.convert('RGB')
            else:
                img = img.convert('RGB')

            # 将单帧图像转换为JPG
            img_format = 'JPEG'
            base_name = os.path.splitext(filename)[0]
            jpg_filename = f"{base_name}.jpg"
            img.save(os.path.join(temp_folder, jpg_filename), img_format)
            print(f"Converted {filename} to JPG")

def convert_jpg_to_individual_pdfs(temp_folder, output_folder):
    # 遍历临时文件夹中的所有JPG文件
    for jpg_filename in os.listdir(temp_folder):
        if jpg_filename.lower().endswith('.jpg'):
            # 打开JPG图像
            img_path = os.path.join(temp_folder, jpg_filename)
            img = Image.open(img_path)
            width, height = img.size

            # 创建与图像尺寸相匹配的PDF页面
            pdf_filename = f"{os.path.splitext(jpg_filename)[0]}.pdf"
            c = canvas.Canvas(os.path.join(output_folder, pdf_filename), pagesize=(width, height))

            # 将JPG图像添加到PDF
            c.drawImage(img_path, 0, 0, width=width, height=height)
            print(f"Added {jpg_filename} to {pdf_filename}")
            
            # 保存PDF文件
            c.save()
            print(f"PDF file '{pdf_filename}' created.")

def merge_pdfs(input_folder, output_folder):
    # 确保输出文件夹存在
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # 存储文件的字典，键是考生号，值是文件列表
    pdf_dict = {}

    # 遍历输入文件夹中的所有文件
    for filename in os.listdir(input_folder):
        if filename.endswith('.pdf'):
            # 提取考生号、姓名和文件描述
            parts = filename.split(' - ')
            if len(parts) >= 3:
                student_id = parts[0]  # 考生号
                name = parts[1]  # 姓名
                file_description = parts[2].split('.')[0]  # 文件描述，去掉.pdf扩展名
                # 将文件添加到字典中对应的列表
                key = f"{student_id} - {name}"
                if key in pdf_dict:
                    pdf_dict[key].append(filename)
                else:
                    pdf_dict[key] = [filename]

    # 合并每个列表中的PDF文件
    for key, files in pdf_dict.items():
        merger = PdfMerger()
        for file in files:
            file_path = os.path.join(input_folder, file)
            merger.append(file_path)
        
        # 提取考生号和姓名
        student_id, name = key.split(' - ')
        # 合并后的文件名，包含考生号、姓名和文件数量
        output_filename = f"{student_id}_{name}_{len(files)}.pdf"
        output_path = os.path.join(output_folder, output_filename)
        merger.write(output_path)
        merger.close()
        print(f"Merged {len(files)} files into {output_path}")

def stu_dict(folder_path):
    # 遍历指定文件夹中的所有子文件夹
    for folder_name in os.listdir(folder_path):
        # 检查文件夹名称是否符合命名规则
        if ' - ' in folder_name and '_files' in folder_name:
            # 分割文件夹名称以提取考生号和姓名
            parts = folder_name.split(' - ')
            student_id = parts[0].strip()  # 使用 strip() 去除可能的前后空格
            name = parts[1].split(' - ')[0].strip()  # 使用 strip() 去除可能的前后空格
            
            # 将考生号和姓名添加到字典中
            candidates_dict[student_id] = name
    return candidates_dict  # 返回填充后的字典

def contains_student_id(file_name, candidates_dict):
    # 去除文件扩展名
    file_name_without_extension = os.path.splitext(file_name)[0]
    
    # 尝试从文件名中提取考生号
    for student_id in candidates_dict.keys():
        if student_id in file_name_without_extension:
            return student_id  # 返回找到的考生号
    return None  # 如果没有找到考生号，返回 None

def rename_file(files_folder_path, candidates_dict):
    # 遍历文件夹中的所有文件
    for file_name in os.listdir(files_folder_path):
        student_id = contains_student_id(file_name, candidates_dict)
        if student_id:
            # 获取对应的姓名
            name = candidates_dict[student_id]
            # 获取文件的扩展名
            file_extension = os.path.splitext(file_name)[1]
            
            # 构造新的文件名
            new_file_name = f"{student_id} - {name} - 未知项目"
            # 构造完整的新文件名
            new_file_name_with_extension = f"{new_file_name}{file_extension}"
            
            # 检查目标文件名是否已经存在
            target_file_path = os.path.join(files_folder_path, new_file_name_with_extension)
            if not os.path.exists(target_file_path):
                # 重命名文件
                os.rename(os.path.join(files_folder_path, file_name), target_file_path)
                print(f"文件 {file_name} 已重命名为 {new_file_name_with_extension}")
            else:
                # 如果文件已存在，将新文件名改为新的文件名加上 "_1"
                new_file_name_with_suffix = f"{new_file_name}_1"
                new_file_name_with_extension_and_suffix = f"{new_file_name_with_suffix}{file_extension}"
                new_target_file_path = os.path.join(files_folder_path, new_file_name_with_extension_and_suffix)
                if not os.path.exists(new_target_file_path):
                    os.rename(os.path.join(files_folder_path, file_name), new_target_file_path)
                    print(f"文件 {file_name} 已重命名为 {new_file_name_with_extension_and_suffix}")
                else:
                    # 如果重命名后的文件名仍然存在，继续添加 "_1" 直到找到未使用的文件名
                    counter = 2
                    while True:
                        new_file_name_with_extension_and_suffix = f"{new_file_name}_{counter}{file_extension}"
                        new_target_file_path = os.path.join(files_folder_path, new_file_name_with_extension_and_suffix)
                        if not os.path.exists(new_target_file_path):
                            os.rename(os.path.join(files_folder_path, file_name), new_target_file_path)
                            print(f"文件 {file_name} 已重命名为 {new_file_name_with_extension_and_suffix}")
                            break
                        counter += 1

input_folder = './source_folder'  # 连带着文件夹，把分类好的文件全部丢进去
output_folder = './target_folder'  # 替换为你的pdf目标文件夹路径
temp_folder = './temp_jpg'  # 临时文件夹路径，用于存放JPG文件
final_folder = './final_folder'   # 临时文件夹路径，用于存放中间文件


# 现将source_folder里面的htm文件转换成pdf的形式
convert_all_html_in_folder(input_folder, output_folder)

# 再将source_folder里面的gif形式转换成jpg的形式
convert_gif_to_jpg(input_folder, temp_folder)

# 填充字典：从source中获取考生号和姓名之间的对应关系
candidates_dict = stu_dict(input_folder)  

# 重命名jpg文件夹的文件，确保能被jpg能正确被转化成pdf
rename_file(temp_folder, candidates_dict)  

# 再将jpg转换成独立的pdf
convert_jpg_to_individual_pdfs(temp_folder, output_folder)

# 最后合并gif生成的pdf和原本htm生成的pdf
merge_pdfs(output_folder, final_folder)

